package com.bio.action.user;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.bio.action.AbstractAction;
import com.bio.entity.user.Company;
import com.bio.entity.user.Position;
import com.bio.entity.user.User;
import com.bio.entity.user.Usertype;
import com.bio.exception.OperationException;
import com.bio.service.user.CompanyService;
import com.bio.service.user.PositionService;
import com.bio.service.user.UserService;
import com.bio.service.user.UsertypeService;
import com.bio.utils.Constants;
import com.bio.utils.Environment;
import com.bio.utils.mail.MailServer;

//@ParentPackage("authorityInterceptor")
@Namespace("/user")
@Results( {
		@Result(name = "toregist", location = "/WEB-INF/views/user/registUser.jsp", type = "dispatcher"),
		@Result(name = "registFail", location = "/regist.jsp",params={"failInfo","${operateResult.message}"}, type = "redirect"),
		@Result(name = "addUserFail", location = "/WEB-INF/views/user/addUser.jsp", type = "dispatcher"),
		@Result(name = "login", location = "/system.jsp",params={"failInfo","${operateResult.message}"}, type = "redirect"),
		@Result(name = "list", location = "/WEB-INF/views/user/listUser.jsp", type = "dispatcher"),
		@Result(name = "tolist", location = "user!list", type = "redirect"),
		@Result(name = "showMyInfo", location = "/WEB-INF/views/user/showMyInfo.jsp", type = "dispatcher"),
		@Result(name = "toShowMyInfo", location = "user!showMyInfo", type = "redirect"),
		@Result(name = "edit", location = "/WEB-INF/views/user/editUser.jsp", type = "dispatcher"),
		@Result(name = "editFail", location = "/WEB-INF/views/user/editUser.jsp", type = "dispatcher"),
		@Result(name = "editSelf", location = "/WEB-INF/views/user/editUserBySelf.jsp", type = "dispatcher"),
		@Result(name = "ajaxResult", location = "/WEB-INF/views/user/ajaxResult.jsp", type = "dispatcher"),
		@Result(name = "add", location = "/WEB-INF/views/user/addUser.jsp", type = "dispatcher"),
		@Result(name = "listMyEmployees", location = "/WEB-INF/views/user/listMyEmployees.jsp", type = "dispatcher"),
		@Result(name = "editEmployee", location = "/WEB-INF/views/user/editEmployee.jsp", type = "dispatcher"),
		@Result(name = "tolistMyEmployees", location = "/WEB-INF/views/user/welcome.jsp", type = "dispatcher"),
		@Result(name = "findPassword", location = "/findPassword.jsp", type = "dispatcher"),
		@Result(name = "resetPassword", location = "/resetPassword.jsp", type = "dispatcher"),
		@Result(name = "loginSuccess", location = "/home/home!listHomePage", type = "redirect"),
		@Result(name = "logout", location = "/system.jsp", type = "redirect"),
		@Result(name = "success", location = "listMyEmployees", type = "chain")})
public class UserAction extends AbstractAction<User, UserService> {
	
	public UserAction(UserService userService) {
		super(userService);
	}
	
	Logger logger = Logger.getLogger(UserAction.class);

	private static final long serialVersionUID = -7113055439943433200L;

	private String json;
	
	private User user;
	
	private String verifyCode;
	
	private List<Company> allCompanys;
	
	private Company company;
	
	private List<Position> allPositions;
	
	private UserService userService;
	
	private CompanyService companyService;
	
	private PositionService positionService;
	
	private String verifyResetCode;
	
	private String email;
	
	private final static String MEDICAL_USER_COOKIE_KEY = "MEDICAL_USER_";
	
	private UsertypeService usertypeService;
	
	private List<Usertype> allUsertypes;

	@Action(value="login")
	public String login() throws Exception {
		logger.info("login action");
		String sessionVerifyCode = (String)ServletActionContext.getRequest().getSession().getAttribute("verifyCode");
		operateResult = userService.login(user.getEmail(), user.getPassword(), verifyCode, sessionVerifyCode);
		if(operateResult.isSuccess()){
			User userTmp = (User)operateResult.getObject();
			Environment.initialize(userTmp);
			ServletActionContext.getRequest().getSession().setAttribute(MEDICAL_USER_COOKIE_KEY + "TYPE", userTmp.getUserTypeId());
			
			return "loginSuccess";
		}
		ServletActionContext.getRequest().setAttribute(Constants.Operation.FAIL, operateResult.getMessage());
		return "login";
	}
	
	public String list(){
		pagination.setCurrentIndex(this.getCurrentIndex());
        this.pager = userService.findAllByPager(pagination);
		return "list";
	}
	
	public String findPassword(){
		this.user = this.service.getUserByEmail(user.getEmail());
		if(null == user){
			this.json = "该用户不存在，请查实。";
			return "findPassword";
		}
		MailServer ms = new MailServer();
		this.verifyResetCode = String.valueOf(Calendar.getInstance().getTimeInMillis());
		ServletActionContext.getRequest().getSession().setAttribute(MEDICAL_USER_COOKIE_KEY + "VERIFY_RESET_CODE", verifyResetCode);
		boolean sendResult = ms.sendFindPasswordMail(user.getEmail(), verifyResetCode);
		if(sendResult){
			this.json = "邮件已发送到注册邮箱，请查收。";
		} else {
			this.json = "邮件发送失败，请重试。";
		}
		return "findPassword";
	}
	
	public String toResetPassword(){
		String code = (String) ServletActionContext.getRequest().getSession().getAttribute(MEDICAL_USER_COOKIE_KEY + "VERIFY_RESET_CODE");
		if(code.equals(this.verifyResetCode)){
			logger.info(email);
		    return "resetPassword";
		} else {
			this.operateResult.setMessage("链接已失效，请重新发送重设密码邮件");
			return "login";
		}
	}
	
	public String resetPassword(){
		User oldUser = this.service.getUserByEmail(user.getEmail());
		if(null != oldUser){
			oldUser.setPassword(user.getPassword());
			this.service.saveByMd5(oldUser);
		} else {
			this.json = "用户不存在";
			return "resetPassword";
		}
		Environment.initialize(oldUser);
		//ServletActionContext.getRequest().getSession().setAttribute(MEDICAL_USER_COOKIE_KEY + "TYPE", oldUser.getType());
		return "toShowMyInfo";
	}
	
	public String add(){
		User user = Environment.Session.getUser();
		this.company = this.companyService.get(Environment.Session.getCompanyId());
		this.allPositions = positionService.findAllByCompanyId(company.getId());
		if(Constants.UserType.SUPER_ADMIN.equals(user.getUserTypeId())){
			this.allUsertypes = this.usertypeService.findPagerByCompanyId(null, null).getResult();
		} else {
			this.allUsertypes = this.usertypeService.findPagerByCompanyId(null, Environment.Session.getCompanyId()).getResult();
		}
		return "add";
	}
	
	public String save(){
		Calendar now = Calendar.getInstance();
		this.user.setCreatedDate(now);
		com.bio.exception.Result result = userService.accountValidate(user);
		if(!result.isSuccess()){
			ServletActionContext.getRequest().setAttribute(Constants.Operation.FAIL, result.getMessage());
			this.allCompanys = this.companyService.findAllByPager(null).getResult();
			return "addUserFail";
		}
		userService.saveByMd5(this.user);
		return "tolist";
	}
	
	public String update(){
	    User oldUser = this.service.get(this.user.getId());
		this.user.setUpdatedDate(Calendar.getInstance());
		this.user.setCreatedDate(oldUser.getCreatedDate());
		
		com.bio.exception.Result result = userService.accountValidate(user);
		if(!result.isSuccess()){
			ServletActionContext.getRequest().setAttribute(Constants.Operation.FAIL, result.getMessage());
			this.allCompanys = this.companyService.findAllByPager(null).getResult();
			return "editFail";
		}
		if(this.user.getPassword().equals(oldUser.getPassword())){
			userService.save(user);
		} else {
			userService.saveByMd5(this.user);
		}
		return "tolist";
	}
	
	public String updateBySelf(){
		User oldUser = this.service.get(this.user.getId());
		this.user.setUpdatedDate(Calendar.getInstance());
		this.user.setCreatedDate(oldUser.getCreatedDate());
		//加入公司职位
		if(null != this.user.getPositionId()){
		    this.user.setPositionName(this.positionService.get(this.user.getPositionId()).getName());
		}
		if(null != this.user.getCompanyId()){
		    this.user.setCompanyName(this.companyService.get(this.user.getCompanyId()).getName());
		}
		com.bio.exception.Result result = userService.accountValidate(user);
		if(!result.isSuccess()){
			ServletActionContext.getRequest().setAttribute(Constants.Operation.FAIL, result.getMessage());
			return "editSelf";
		}
		if(this.user.getPassword().equals(oldUser.getPassword())){
			userService.save(user);
		} else {
			userService.saveByMd5(this.user);
		}
		return "toShowMyInfo";
	}
	
	@Action(value="regist")
	public String regist(){
		Calendar now = Calendar.getInstance();
		this.user.setCreatedDate(now);
		//试用到期时间
	    now.add(Calendar.MONTH, Constants.User.PROBATIONARY_MONTH);
		operateResult = userService.accountValidate(user);
		if(!operateResult.isSuccess()){
			ServletActionContext.getRequest().setAttribute(Constants.Operation.FAIL, operateResult.getMessage());
			return "registFail";
		}
		user = userService.saveByMd5(this.user);
		//发送注册邮件
		MailServer ms = new MailServer();
		ms.sendRegistSuccessMail(user.getEmail());
		Environment.initialize(user);
		//ServletActionContext.getRequest().getSession().setAttribute(MEDICAL_USER_COOKIE_KEY + "TYPE", user.getType());
		return "toShowMyInfo";
	}

	
	public String remove() throws OperationException {
        this.service.remove(this.id);
        return "tolist";
    }

	 public String deleteAll() 
	    {
	    	for(Long id : ids)
	    	{
	    		this.service.remove(id);
	    	}
	    	return "tolist";
	    }
	
	@Action(value="showMyInfo")
	public String showMyInfo(){
		this.id = Environment.Session.getUserId();
		this.user = this.service.get(id);
		return "showMyInfo";
	}
	
	public String toEditSelf(){
		this.id = Environment.Session.getUserId();
		this.user = this.service.get(id);
		return "editSelf";
	}
	
	public String toEdit(){
		this.user = this.service.get(id);
		this.company = this.companyService.get(Environment.Session.getCompanyId());
		this.allPositions = positionService.findAllByCompanyId(company.getId());
		if(Constants.UserType.SUPER_ADMIN.equals(user.getUserTypeId())){
			this.allUsertypes = this.usertypeService.findPagerByCompanyId(null, null).getResult();
		} else {
			this.allUsertypes = this.usertypeService.findPagerByCompanyId(null, Environment.Session.getCompanyId()).getResult();
		}
		return "edit";
	}
	//,interceptorRefs=@InterceptorRef("authInterceptor")
	@Action(value="listMyEmployees")
	public String listMyEmployees(){
		Long companyId = Environment.Session.getCompanyId();
		pagination.setCurrentIndex(this.getCurrentIndex());
		this.pager = this.service.findPagerByCompanyId(pagination, companyId);
		return "listMyEmployees";
	}
	
	public String toEditEmployee(){
		this.user = this.service.get(id);
		if(null != this.user.getCompanyId()){
		    this.allPositions = this.positionService.findAllByCompanyId(user.getCompanyId());
		}
		this.allUsertypes = this.usertypeService.findPagerByCompanyId(null, Environment.Session.getCompanyId()).getResult();
		return "editEmployee";
	}
	
	public String updateEmployee(){
		User oldUser = this.service.get(this.user.getId());
		this.user.setUpdatedDate(Calendar.getInstance());
		this.user.setCreatedDate(oldUser.getCreatedDate());
		//加入公司职位
		if(null != this.user.getPositionId()){
		    this.user.setPositionName(this.positionService.get(this.user.getPositionId()).getName());
		}
		com.bio.exception.Result result = userService.accountValidate(user);
		if(!result.isSuccess()){
			ServletActionContext.getRequest().setAttribute(Constants.Operation.FAIL, result.getMessage());
			user = service.get(user.getId());
			if(null != user.getCompanyId()){
			    this.allPositions = this.positionService.findAllByCompanyId(user.getCompanyId());
			}
			return "editEmployee";
		}
		if(this.user.getPassword().equals(oldUser.getPassword())){
			userService.save(user);
		} else {
			userService.saveByMd5(this.user);
		}
		return "success";
	}
	
	public void ajaxAccountValidate() throws IOException{
		//TODO: 根据用户名拿用户
		com.bio.exception.Result result = userService.accountValidate(user);
		
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setContentType("text/xml;charset=utf-8");
		PrintWriter out = response.getWriter();
		JSONObject jObject = JSONObject.fromObject(result);
		out.write(jObject.toString());
		out.flush();
		out.close();
	}
	
	public String logout(){
		Environment.getSession().invalidate();
		return "logout";
	}
	
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String getJson() {
		return json;
	}

	public void setJson(String json) {
		this.json = json;
	}

	public void setCompanyService(CompanyService companyService) {
		this.companyService = companyService;
	}

	public List<Company> getAllCompanys() {
		return allCompanys;
	}

	public void setAllCompanys(List<Company> allCompanys) {
		this.allCompanys = allCompanys;
	}

	public void setPositionService(PositionService positionService) {
		this.positionService = positionService;
	}

	public List<Position> getAllPositions() {
		return allPositions;
	}

	public void setAllPositions(List<Position> allPositions) {
		this.allPositions = allPositions;
	}

	public String getVerifyCode() {
		return verifyCode;
	}

	public void setVerifyCode(String verifyCode) {
		this.verifyCode = verifyCode;
	}

	public String getVerifyResetCode() {
		return verifyResetCode;
	}

	public void setVerifyResetCode(String verifyResetCode) {
		this.verifyResetCode = verifyResetCode;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public List<Usertype> getAllUsertypes() {
		return allUsertypes;
	}

	public void setAllUsertypes(List<Usertype> allUsertypes) {
		this.allUsertypes = allUsertypes;
	}

	public void setUsertypeService(UsertypeService usertypeService) {
		this.usertypeService = usertypeService;
	}

	public Company getCompany() {
		return company;
	}

	public void setCompany(Company company) {
		this.company = company;
	}
	
}
